import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
#线性模型
def model(x,theta):
    return x.dot(theta)
#sigmoid函数
def sigmoid(z):
    return 1/(1+np.exp(-z))
#代价函数
def cost(h,y):
    m=len(y)
    return -1/m*np.sum(y*np.log(h)+(1-y)*np.log(1-h))
#正向传播
def FP(x,theta1,theta2,theta3):
    a1=x
    z2=model(a1,theta1)
    a2=sigmoid(z2)
    z3=model(a2,theta2)
    a3=sigmoid(z3)
    z4=model(a3,theta3)
    a4=sigmoid(z4)
    return a2,a3,a4
#反向传播
def BP(x,y,theta1,theta2,theta3,a2,a3,a4,alpha):
    s4=a4-y
    s3=s4.dot(theta3.T)*(a3*(1-a3))
    s2=s3.dot(theta2.T)*(a2*(1-a2))

    m=len(y)
    dt3=1/m*a3.T.dot(s4)
    dt2=1/m*a2.T.dot(s3)
    dt1=1/m*x.T.dot(s2)

    theta3-=alpha*dt3
    theta2-=alpha*dt2
    theta1-=alpha*dt1
    return theta1,theta2,theta3
#梯度下降
def grad(x,y,iter0=2000,alpha=0.1):
    m,n=x.shape
    theta1=np.random.randn(n,50)
    theta2=np.random.randn(50,100)
    theta3=np.random.randn(100,1)
    J=np.zeros(iter0)
    for i in range(iter0):
        a2, a3, a4=FP(x,theta1,theta2,theta3)
        J[i]=cost(a4,y)
        theta1, theta2, theta3=BP(x,y,theta1,theta2,theta3,a2,a3,a4,alpha)
    return theta1,theta2,theta3,J,a4

def score(h,y):
    return np.mean(y==[h>0.5])
#加载数据  训练模型
if __name__ == '__main__':
    np.random.seed(1)
    cancer=load_breast_cancer()
    x=cancer.data
    y=cancer.target.reshape(-1,1)

    miu=np.mean(x,axis=0)
    sigma=np.std(x,axis=0)
    x=(x-miu)/sigma

    X=np.c_[np.ones(len(x)),x]

    theta1, theta2, theta3, J, a4=grad(X,y)

    plt.plot(J)
    plt.show()

    print(score(a4,y))